package lei.m_线程池_事物;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 优化版：结合悲观锁和乐观锁的多线程事务处理示例
 * 主要优化点：
 * 1. 减少不必要的线程等待时间
 * 2. 优化线程池配置
 * 3. 减少任务数量和复杂度
 * 4. 优化锁竞争
 */
public class OptimizedThreadPoolWithLocksExampleV2 {

    // 优化的线程池配置
    private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();
    private static final int MAX_POOL_SIZE = CORE_POOL_SIZE * 2;
    private static final int QUEUE_CAPACITY = 50; // 减小队列容量
    private static final long KEEP_ALIVE_TIME = 30L; // 缩短线程空闲时间

    // 优化的线程池
    private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(
            CORE_POOL_SIZE,
            MAX_POOL_SIZE,
            KEEP_ALIVE_TIME,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(QUEUE_CAPACITY), // 使用有界数组队列
            new ThreadFactory() {
                private final AtomicInteger threadNumber = new AtomicInteger(1);

                @Override
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r, "OptimizedThread-" + threadNumber.getAndIncrement());
                    t.setDaemon(false);
                    t.setPriority(Thread.NORM_PRIORITY); // 设置标准优先级
                    return t;
                }
            },
            new ThreadPoolExecutor.CallerRunsPolicy()
    );

    // 预热线程池
    static {
        executor.prestartAllCoreThreads();
    }

    // 事务上下文传递
    private static final ThreadLocal<TransactionContext> transactionContext =
            new ThreadLocal<>();

    // 模拟共享资源 - 银行账户
    static class BankAccount {
        private final String accountId;
        private volatile double balance;
        private final AtomicLong version = new AtomicLong(0);
        private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

        public BankAccount(String accountId, double initialBalance) {
            this.accountId = accountId;
            this.balance = initialBalance;
        }

        // 优化的悲观锁转账 - 减少锁持有时间
        public boolean transferWithPessimisticLock(BankAccount toAccount, double amount) {
            // 避免死锁：按账户ID排序加锁
            BankAccount firstLock = this.accountId.compareTo(toAccount.accountId) <= 0 ? this : toAccount;
            BankAccount secondLock = this.accountId.compareTo(toAccount.accountId) <= 0 ? toAccount : this;

            firstLock.lock.writeLock().lock();
            try {
                secondLock.lock.writeLock().lock();
                try {
                    // 快速检查余额
                    if (this.balance < amount) {
                        return false;
                    }

                    // 执行转账
                    this.balance -= amount;
                    toAccount.balance += amount;

                    return true;
                } finally {
                    secondLock.lock.writeLock().unlock();
                }
            } finally {
                firstLock.lock.writeLock().unlock();
            }
        }

        // 优化的乐观锁转账 - 减少重试次数和等待时间
        public boolean transferWithOptimisticLock(BankAccount toAccount, double amount) {
            int retryCount = 0;
            final int maxRetries = 2; // 减少重试次数

            while (retryCount < maxRetries) {
                // 无等待快速读取
                long fromVersion = this.version.get();
                long toVersion = toAccount.version.get();
                double fromBalance = this.balance;
                double toBalance = toAccount.balance;

                // 快速检查余额
                if (fromBalance < amount) {
                    return false;
                }

                // 尝试原子更新
                if (this.version.compareAndSet(fromVersion, fromVersion + 1)) {
                    if (toAccount.version.compareAndSet(toVersion, toVersion + 1)) {
                        // 原子更新余额
                        this.balance = fromBalance - amount;
                        toAccount.balance = toBalance + amount;
                        return true;
                    } else {
                        // 轻量级回退
                        this.version.decrementAndGet(); // 回退版本号
                    }
                }
                retryCount++;
            }
            return false;
        }

        // 无锁查询余额
        public double getBalance() {
            return balance;
        }

        public String getAccountId() {
            return accountId;
        }
    }

    static class TransactionContext {
        private boolean inTransaction = false;
        private String transactionId;

        public TransactionContext(String transactionId) {
            this.transactionId = transactionId;
        }

        // getters and setters
        public boolean isInTransaction() { return inTransaction; }
        public void setInTransaction(boolean inTransaction) { this.inTransaction = inTransaction; }
        public String getTransactionId() { return transactionId; }
        public void setTransactionId(String transactionId) { this.transactionId = transactionId; }
    }

    // 共享的银行账户
    private static final BankAccount accountA = new BankAccount("ACCOUNT_A", 10000.0);
    private static final BankAccount accountB = new BankAccount("ACCOUNT_B", 10000.0);
    private static final BankAccount accountC = new BankAccount("ACCOUNT_C", 10000.0);

    public static void main(String[] args) {
        System.out.println("=== 优化版多线程结合悲观锁和乐观锁示例 ===");
        System.out.println("初始余额: A=" + accountA.getBalance() +
                ", B=" + accountB.getBalance() +
                ", C=" + accountC.getBalance());

        long startTime = System.currentTimeMillis();

        // 减少任务数量，提高执行效率
        for (int i = 0; i < 10; i++) { // 从15减少到10
            final int taskId = i;
            executor.submit(() -> {
                try {
                    // 设置事务上下文
                    TransactionContext context = new TransactionContext("TX-" + taskId);
                    context.setInTransaction(true);
                    transactionContext.set(context);

                    // 根据任务ID决定使用哪种锁机制
                    if (taskId % 2 == 0) {
                        // 偶数任务使用悲观锁
                        performTransferWithPessimisticLock(taskId);
                    } else {
                        // 奇数任务使用乐观锁
                        performTransferWithOptimisticLock(taskId);
                    }

                } catch (Exception e) {
                    System.err.println("任务执行失败: " + e.getMessage());
                } finally {
                    transactionContext.remove();
                }
            });
        }

        // 优化的线程池关闭
        shutdownExecutor();

        System.out.println("=== 最终余额 ===");
        System.out.println("账户A余额: " + accountA.getBalance());
        System.out.println("账户B余额: " + accountB.getBalance());
        System.out.println("账户C余额: " + accountC.getBalance());
        System.out.println("总余额: " + (accountA.getBalance() + accountB.getBalance() + accountC.getBalance()));

        long endTime = System.currentTimeMillis();
        System.out.println("总执行时间: " + (endTime - startTime) + " ms");
    }

    // 优化的悲观锁转账执行
    private static void performTransferWithPessimisticLock(int taskId) {
        boolean success = false;

        switch (taskId % 3) {
            case 0:
                success = accountA.transferWithPessimisticLock(accountB, 50.0);
                break;
            case 1:
                success = accountB.transferWithPessimisticLock(accountC, 30.0);
                break;
            case 2:
                success = accountC.transferWithPessimisticLock(accountA, 20.0);
                break;
        }

        if (success) {
            System.out.println("任务 " + taskId + " 悲观锁转账成功，线程: " + Thread.currentThread().getName());
        } else {
            System.out.println("任务 " + taskId + " 悲观锁转账失败，线程: " + Thread.currentThread().getName());
        }
    }

    // 优化的乐观锁转账执行
    private static void performTransferWithOptimisticLock(int taskId) {
        boolean success = false;

        switch (taskId % 3) {
            case 0:
                success = accountA.transferWithOptimisticLock(accountB, 50.0);
                break;
            case 1:
                success = accountB.transferWithOptimisticLock(accountC, 30.0);
                break;
            case 2:
                success = accountC.transferWithOptimisticLock(accountA, 20.0);
                break;
        }

        if (success) {
            System.out.println("任务 " + taskId + " 乐观锁转账成功，线程: " + Thread.currentThread().getName());
        } else {
            System.out.println("任务 " + taskId + " 乐观锁转账失败，线程: " + Thread.currentThread().getName());
        }
    }

    // 优化的线程池关闭方法
    private static void shutdownExecutor() {
        executor.shutdown();
        try {
            // 缩短等待时间
            if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
                System.out.println("线程池关闭超时，强制关闭");
                executor.shutdownNow();
                // 等待强制关闭完成
                if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
                    System.err.println("线程池无法正常关闭");
                }
            }
        } catch (InterruptedException e) {
            System.err.println("线程池关闭被中断");
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
        System.out.println("线程池已关闭");
    }
}
